#include "flash.h"

#include "AppLayer.h"
#include "menu.h"

/* Private define ------------------------------------------------------------*/
#define FLASH_USER_START_ADDR 0x08007F80

/* Private variables ---------------------------------------------------------*/

static uint32_t flash_data[64] = {0};


/**
 * @brief  擦除Flash
 * @param  无
 * @retval 无
 */
static void APP_FlashErase(void)
{
	uint32_t PAGEError = 0;
	FLASH_EraseInitTypeDef EraseInitStruct;

	EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGEERASE;		   /* 擦写类型FLASH_TYPEERASE_PAGEERASE=Page擦, FLASH_TYPEERASE_SECTORERASE=Sector擦 */
	EraseInitStruct.PageAddress = FLASH_USER_START_ADDR;		   /* 擦写起始地址 */
	EraseInitStruct.NbPages = sizeof(flash_data) / FLASH_PAGE_SIZE;	   /* 需要擦写的页数量 */
	if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) /* 执行page擦除,PAGEError返回擦写错误的page,返回0xFFFFFFFF,表示擦写成功 */
	{
		// Error_Handler();
		printf("*******ERROR-Flash - 1 \r\n");
	}
}

/**
 * @brief  写入Flash
 * @param  无
 * @retval 无
 */
static void APP_FlashProgram(void)
{
	uint32_t flash_program_start = FLASH_USER_START_ADDR;				 /* flash写起始地址 */
	uint32_t flash_program_end = (FLASH_USER_START_ADDR + sizeof(flash_data)); /* flash写结束地址 */
	uint32_t *src = (uint32_t *)flash_data;									 /* 数组指针 */

	while (flash_program_start < flash_program_end)
	{
		if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_PAGE, flash_program_start, src) == HAL_OK) /* 执行Program */
		{
			flash_program_start += FLASH_PAGE_SIZE; /* flash起始指针指向第一个page */
			src += FLASH_PAGE_SIZE / 4;				/* 更新数据指针 */
		}
	}
}

/**
 * @brief  查空Flash
 * @param  无
 * @retval 无
 */
static void APP_FlashBlank(void)
{
	uint32_t addr = 0;

	while (addr < sizeof(flash_data))
	{
		if (0xFFFFFFFF != HW32_REG(FLASH_USER_START_ADDR + addr))
		{
			printf("*******ERROR-Flash - 2 \r\n");
		}
		addr += 4;
	}
}

/**
 * @brief  校验Flash
 * @param  无
 * @retval 无
 */
static void APP_FlashVerify(void)
{
	uint32_t addr = 0;

	while (addr < sizeof(flash_data))
	{
		if (flash_data[addr / 4] != HW32_REG(FLASH_USER_START_ADDR + addr))
		{
			// Error_Handler();
			printf("*******ERROR-Flash - 3 \r\n");
		}
		addr += 4;
	}
}

// flash 数据转换



void flash_data_encrypt(uint16_t data, uint32_t *pdata)
{
	uint32_t data_buff = 0;

	data_buff = 0xFFFF - data;
	data_buff <<= 16;
	*pdata = data | data_buff;
}

// 数据加密
void flash_datas_encrypt(void)
{
	flash_data_encrypt(0x1234, &flash_data[1]); // 0x1234
	flash_data_encrypt(0x5678, &flash_data[2]); // 0x5678

	flash_data_encrypt(Heating_Platform.work_time, &flash_data[3]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[0].set_control_temp, &flash_data[4]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[0].set_work_time, &flash_data[5]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[1].set_control_temp, &flash_data[6]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[1].set_work_time, &flash_data[7]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[2].set_control_temp, &flash_data[8]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[2].set_work_time, &flash_data[9]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[3].set_control_temp, &flash_data[10]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[3].set_work_time, &flash_data[11]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[4].set_control_temp, &flash_data[12]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[4].set_work_time, &flash_data[13]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[5].set_control_temp, &flash_data[14]);
	flash_data_encrypt(Heating_Platform.stHeating_Control[5].set_work_time, &flash_data[15]);

	flash_data_encrypt(Heating_Platform.stReflowSoldering[0].stHeating_Phases[0].set_control_temp, &flash_data[16]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[0].stHeating_Phases[1].set_control_temp, &flash_data[17]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[0].stHeating_Phases[2].set_control_temp, &flash_data[18]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[0].stHeating_Phases[0].set_control_time, &flash_data[19]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[0].stHeating_Phases[1].set_control_time, &flash_data[20]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[0].stHeating_Phases[2].set_control_time, &flash_data[21]);

	flash_data_encrypt(Heating_Platform.stReflowSoldering[1].stHeating_Phases[0].set_control_temp, &flash_data[22]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[1].stHeating_Phases[1].set_control_temp, &flash_data[23]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[1].stHeating_Phases[2].set_control_temp, &flash_data[24]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[1].stHeating_Phases[0].set_control_time, &flash_data[25]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[1].stHeating_Phases[1].set_control_time, &flash_data[26]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[1].stHeating_Phases[2].set_control_time, &flash_data[27]);

	flash_data_encrypt(Heating_Platform.stReflowSoldering[2].stHeating_Phases[0].set_control_temp, &flash_data[28]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[2].stHeating_Phases[1].set_control_temp, &flash_data[29]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[2].stHeating_Phases[2].set_control_temp, &flash_data[30]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[2].stHeating_Phases[0].set_control_time, &flash_data[31]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[2].stHeating_Phases[1].set_control_time, &flash_data[32]);
	flash_data_encrypt(Heating_Platform.stReflowSoldering[2].stHeating_Phases[2].set_control_time, &flash_data[33]);

	flash_data_encrypt(Heating_Platform.calibrate_temp, &flash_data[34]);
	flash_data_encrypt(Heating_Platform.Kp, &flash_data[35]);
	flash_data_encrypt(Heating_Platform.Ki, &flash_data[36]);
	flash_data_encrypt(Heating_Platform.Kd, &flash_data[37]);

	flash_data_encrypt(Heating_Platform.max_power, &flash_data[38]);

	flash_data_encrypt(0xABCD, &flash_data[39]);
	flash_data_encrypt(0xEFFF, &flash_data[40]);
}

// 数据解密
uint16_t flash_data_decrypt(uint32_t *pdata, uint8_t *pflag)
{
	uint32_t data_buff = 0;
	uint16_t data = 0;

	data_buff = *pdata;

	data = data_buff & 0x0000FFFF;
	data_buff = data_buff >> 16;
	if ((data_buff + data) == 0xFFFF)
	{
		*pflag = 1;
		return data;
	}

	*pflag = 0;
	return 0;
}

// 数据恢复
void flash_datas_decrypt(void)
{
	uint8_t flag = 0;

	Heating_Platform.work_time = flash_data_decrypt(&flash_data[3], &flag);
	Heating_Platform.stHeating_Control[0].set_control_temp = flash_data_decrypt(&flash_data[4], &flag);
	Heating_Platform.stHeating_Control[0].set_work_time = flash_data_decrypt(&flash_data[5], &flag);
	Heating_Platform.stHeating_Control[1].set_control_temp = flash_data_decrypt(&flash_data[6], &flag);
	Heating_Platform.stHeating_Control[1].set_work_time = flash_data_decrypt(&flash_data[7], &flag);
	Heating_Platform.stHeating_Control[2].set_control_temp = flash_data_decrypt(&flash_data[8], &flag);
	Heating_Platform.stHeating_Control[2].set_work_time = flash_data_decrypt(&flash_data[9], &flag);
	Heating_Platform.stHeating_Control[3].set_control_temp = flash_data_decrypt(&flash_data[10], &flag);
	Heating_Platform.stHeating_Control[3].set_work_time = flash_data_decrypt(&flash_data[11], &flag);
	Heating_Platform.stHeating_Control[4].set_control_temp = flash_data_decrypt(&flash_data[12], &flag);
	Heating_Platform.stHeating_Control[4].set_work_time = flash_data_decrypt(&flash_data[13], &flag);
	Heating_Platform.stHeating_Control[5].set_control_temp = flash_data_decrypt(&flash_data[14], &flag);
	Heating_Platform.stHeating_Control[5].set_work_time = flash_data_decrypt(&flash_data[15], &flag);
	Heating_Platform.stReflowSoldering[0].stHeating_Phases[0].set_control_temp = flash_data_decrypt(&flash_data[16], &flag);
	Heating_Platform.stReflowSoldering[0].stHeating_Phases[1].set_control_temp = flash_data_decrypt(&flash_data[17], &flag);
	Heating_Platform.stReflowSoldering[0].stHeating_Phases[2].set_control_temp = flash_data_decrypt(&flash_data[18], &flag);
	Heating_Platform.stReflowSoldering[0].stHeating_Phases[0].set_control_time = flash_data_decrypt(&flash_data[19], &flag);
	Heating_Platform.stReflowSoldering[0].stHeating_Phases[1].set_control_time = flash_data_decrypt(&flash_data[20], &flag);
	Heating_Platform.stReflowSoldering[0].stHeating_Phases[2].set_control_time = flash_data_decrypt(&flash_data[21], &flag);
	Heating_Platform.stReflowSoldering[1].stHeating_Phases[0].set_control_temp = flash_data_decrypt(&flash_data[22], &flag);
	Heating_Platform.stReflowSoldering[1].stHeating_Phases[1].set_control_temp = flash_data_decrypt(&flash_data[23], &flag);
	Heating_Platform.stReflowSoldering[1].stHeating_Phases[2].set_control_temp = flash_data_decrypt(&flash_data[24], &flag);
	Heating_Platform.stReflowSoldering[1].stHeating_Phases[0].set_control_time = flash_data_decrypt(&flash_data[25], &flag);
	Heating_Platform.stReflowSoldering[1].stHeating_Phases[1].set_control_time = flash_data_decrypt(&flash_data[26], &flag);
	Heating_Platform.stReflowSoldering[1].stHeating_Phases[2].set_control_time = flash_data_decrypt(&flash_data[27], &flag);
	Heating_Platform.stReflowSoldering[2].stHeating_Phases[0].set_control_temp = flash_data_decrypt(&flash_data[28], &flag);
	Heating_Platform.stReflowSoldering[2].stHeating_Phases[1].set_control_temp = flash_data_decrypt(&flash_data[29], &flag);
	Heating_Platform.stReflowSoldering[2].stHeating_Phases[2].set_control_temp = flash_data_decrypt(&flash_data[30], &flag);
	Heating_Platform.stReflowSoldering[2].stHeating_Phases[0].set_control_time = flash_data_decrypt(&flash_data[31], &flag);
	Heating_Platform.stReflowSoldering[2].stHeating_Phases[1].set_control_time = flash_data_decrypt(&flash_data[32], &flag);
	Heating_Platform.stReflowSoldering[2].stHeating_Phases[2].set_control_time = flash_data_decrypt(&flash_data[33], &flag);
	Heating_Platform.calibrate_temp = flash_data_decrypt(&flash_data[34], &flag);
	Heating_Platform.Kp = flash_data_decrypt(&flash_data[35], &flag);
	Heating_Platform.Ki = flash_data_decrypt(&flash_data[36], &flag);
	Heating_Platform.Kd = flash_data_decrypt(&flash_data[37], &flag);
	Heating_Platform.max_power = flash_data_decrypt(&flash_data[38], &flag);
	
}



// 数据判断
uint8_t flash_data_check(uint32_t data)
{
	uint16_t data_s = (uint16_t)(data & 0x0000FFFF);

	data = data >> 16;
	if ((data + data_s) == 0xFFFF)
	{
		return 1;
	}
	return 0;
}

// 第一次，进行默认数据保存
void flash_data_init(void)
{
	uint8_t i = 0;
	uint8_t j = 0;

	for (i = 0; i < 64; i++)
	{
		flash_data[i] = HW32_REG(FLASH_USER_START_ADDR + i*4);

		if(flash_data[i] != 0xFFFFFFFF)
		{
			// 校验数据 确定数据格式正确   不正确表明该地址数据被占用
			if(flash_data_check(flash_data[i]))
			{
				// 数据正确
				j++;
			}
			else
			{
				return;
			}
		}
	}

	if(j >= 40)
	{
		//数据恢复 // HACK
		if((flash_data_decrypt(&flash_data[0], &i) == 0x1234) && (flash_data_decrypt(&flash_data[1], &i) == 0x5678))
		{
			flash_datas_decrypt();
			#if 1
			printf("flash_data_decrypt ok\r\n");
			for(i = 0; i < 40; i++)
			{
				printf("flash_data[%d] = 0x%x\r\n", i, flash_data[i]);
			}
			#endif
		}
	}
	else if(j == 0)
	{
		// 没有数据，进行默认数据保存
		menu_seting_data_init();
		flash_datas_encrypt();

		/* 解锁FLASH */
		HAL_FLASH_Unlock();

		/* 擦除FLASH */
		APP_FlashErase();

		/* 查空FLASH */
		APP_FlashBlank();

		/* 写FLASH */
		APP_FlashProgram();

		/* 锁定FLASH */
		HAL_FLASH_Lock();

		/* 校验FLASH */
		APP_FlashVerify();
	}

}

// 数据保存
void flash_data_save(void)
{
}

void flash_deal(void)
{
	if(Heating_Platform.flag_write_flash == 1)
	{
		Heating_Platform.flag_write_flash = 0;
		flash_datas_encrypt();
		/* 解锁FLASH */
		HAL_FLASH_Unlock();

		/* 擦除FLASH */
		APP_FlashErase();

		/* 查空FLASH */
		APP_FlashBlank();

		/* 写FLASH */
		APP_FlashProgram();

		/* 锁定FLASH */
		HAL_FLASH_Lock();

		/* 校验FLASH */
		APP_FlashVerify();
	}
}
